<?php
// +----------------------------------------------------------------------
// | 杭州十禾信息科技有限公司
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2015 http://www.shelpe.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: LeePuman <ysyzlsm@163.com>
// +----------------------------------------------------------------------
 
require_once "TopClient.class.php";
 class taobaoAPI{
    
    static private $_instance = NULL;

    private $_access_session = NULL;
    
    private $_nick = NULL;
    
    private $_user_id = NULL;
    
    private $_api = NULL;
    
    private $_top_client = NULL;
    
    private $_redis = NULL;
    
    /* singlone model, private construct*/
    private function  __construct($access_session) {
        $this->_top_client = new TopClient;
        $tmp = session('me');
        if((isset($tmp['type']) && $tmp['type'] == '') || (isset($GLOBALS['IS_AGENT']) && $GLOBALS['IS_AGENT'])) {
            $this->_top_client->setAppkey(TB_AKEY2, TB_SKEY2);
        }
        $this->_access_session = $access_session;
    }

    public function setAccessToken($access_token){
        $this->_access_session = $access_token;
    }

    /* get the singlone instance of taobao api */
    
    public static function init($access_session = null ){
        if( is_null( self::$_instance ) || !isset(self::$_instance) ){
            self::$_instance = new self($access_session);
        } 
        return self::$_instance;
    }

    public static function login($access_session = null ){
        self::$_instance = new self($access_session);
        return self::$_instance;
    }
    
    public static function check($resp){
        $resp = (array) $resp;
        return $resp;
    }
    
    protected function request($req , $access_token = null){
        try{
            if($access_token){
                $this->_access_session = $access_token;
            }
            $resp = $this->_top_client->execute($req , $this->_access_session);
        }catch(Exception $e){
            $this->error($e);
        }         

        return $resp;
    }
    
    public function getSellerCids($user_id , $nick){
        $key = $user_id . "_sellercids";
        $result = $this->getCache($key , "content");
        if(!$result){
            $req = TopClient::init("SellercatsListGetRequest");
            $req->setNick($nick);
            $resp = $this->request($req);
            $result = self::check($resp);
            if($result){
                $this->setCache($key , $result);
            }
        }
        $cids = $result["seller_cats"]->seller_cat;
        return $cids;
    }

    public function getProductById($product_id){
        $cachekey = "product::" . $product_id;
        $resp = $this->_cache->get($cachekey);
        if(!$resp){
            $c = $this->_top_client;
            $req = TopClient::init( "ItemSellerGetRequest" );
            $req->setFields("num_iid,nick,title,pic_url,location,list_time,delist_time,cid");
            $req->setNumIid($product_id);
            $resp = $this->request($req);
            $result = self::check($resp);
            if($result){
                $product = (array) $result["item"];
                $product["product_id"] = $product["num_iid"];
            }
            
            $this->_cache->set( $cachekey , json_encode($product) );
        }else{
            $product = json_decode($resp , true);
        }
        
        return $product;
    
    }
    
    public function getProducts($user_id , $q = "" , $cids = "" , $pageno = 1 , $pagesize = 1){
        $key = $user_id . "::products";
        $c = $this->_top_client;
        $req = $c::init( "ItemsOnsaleGetRequest" );
        $req->setFields("num_iid, title, nick, type, cid, pic_url, num, price,list_time,modified,delist_time");
        $req->setPageSize($pagesize);
        $req->setPageNo($pageno);
        $resp = $this->request($req);
        $result = self::check($resp);
        $products = $result["items"]->item;
        $total = $result["total_results"];
        if( $pagesize * $pageno < $total){
            $nextpage = $pageno + 1;
        }else{
            $nextpage = 0;
        }
        
        return array(
            "products" => $products,
            "pagesize" => $pagesize,
            "pageno" => $pageno,
            "nextpage" => $nextpage
        );
    }

    public function getCampaigns(){
        $req = TopClient::init("SimbaCampaignsGetRequest");
        $resp = $this->request($req, $this->_access_session);
        $campaigns = array();
        $result = self::check($resp);
        $campaigns = $result["campaigns"]->campaign;
        return $campaigns;
    }

    public function getCampaignBudget($campaign_id,$nick=""){
        $c = $this->_top_client;
        $req = $c::init( "SimbaCampaignBudgetGetRequest" );
        $req->setCampaignId($campaign_id);
        //$req->setNick($nick);
        try{
            $resp = $c->execute($req , $this->_access_session);
        }catch(Exception $e){
            $this->error($e);
        }       
        $result = self::check($resp);
        $budget = $result["campaign_budget"]->budget;
        return $budget;
    }
   
    public function getUserBalance($nick){
        $c = $this->_top_client;
        $req = $c::init( "SimbaAccountBalanceGetRequest" );
        //$req->setNick($nick); 
        try{
            $resp = $c->execute($req , $this->_access_session);
        }catch(Exception $e){
            $this->error($e);
        }
        
        // deal with the resp
        $result = self::check($resp);
        $balance = $result["balance"];
        return $balance;
    }
 
    protected function error($e){
        # log the error information
        //halt( $e );
    }
        
    protected function getCache($key , $field = null){
       $time = (int) $this->_redis->hGet($key , "time");
       if( $time + 3600 > time() ){
            if($field){
                $value = $this->_redis->hGet($key , $field);
            }else{
                $value = $this->_redis->Get($key);
            }
            $value = json_decode($value);
            return (array) $value;
       }else{
            return false;
       }
    
    }
    
    protected function setCache($key, $value){
        $this->_redis->hSet($key , "time" , time());
        $this->_redis->hSet($key , "content" , json_encode($value) ) ;   
    }
    
    public function addCampaign($title, $nick=null){
        $c = $this->_top_client;
        $req = $c::init( "SimbaCampaignAddRequest" );
        $req->setTitle($title);
        if($nick) $req->setNick($nick);
        try{
            $resp = $c->execute($req , $this->_access_session);
        }catch(Exception $e){
            $this->error($e);
        }
        
        $campaign = self::check($resp);
        
        return $campaign["campaign"];
    }
    
    /* 
     * magic method to get a request client for api
    */
    public function __call($method, $args){
    	// 传过来的参数优先
    	if(isset($args[1])){
    		$this->setAccessToken($args[1]);
    	} else { 
    		// 否则session中的access_token优先, 如果之前存在 self::_access_session, 
    		// 但是跟session中的不一致, 则会被当前session中的access_token替换.
	    	$user = session('me');
	    	$user_access_token = getUserAccessToken( $user['user_id'] );
	    	if(!$this->_access_session || $this->_access_session != $user_access_token){
	    		$this->_access_session = $user_access_token;
	    	}
    	}

    	//还未成功的话,直接throw
    	if(!$this->_access_session){
			throw new TopClientException("access token没有初始化");    		
    	}
    	
        $c = $this->_top_client;
        $req = TopClient::init( $method );
        if( !isset($args[0]['nick']) ){
        	 $req->putOtherTextParam( 'nick' , UserModel::getSelfOrAuthUserNick());
        }
        
        if(isset($args[0])) 
	        foreach($args[0] as $key=>$value){
	            $req->putOtherTextParam($key , $value);
	        }
	    //$req->putOtherTextParam('start_time' , '2014-12-10');
	    //dump($req);
        $resp = $c->execute($req , $this->_access_session); 
        //dump($resp);
        $result = self::check($resp);
        return $result;
    }
    
}
?>